package com.rede.didiok.sms.event;

import java.util.concurrent.TimeUnit;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rede.didiok.common.constant.conf.RedisConf;
import com.rede.didiok.common.constant.global.Constants;
import com.rede.didiok.common.domainEvent.DomainEvent;
import com.rede.didiok.common.domainEvent.EntityType;
import com.rede.didiok.common.dto.user.NoticeDto;
import com.rede.didiok.common.dto.user.UserWatchDto;
import com.rede.didiok.common.enums.BusinessTypeEnum;
import com.rede.didiok.common.enums.NoticeTypeEnum;
import com.rede.didiok.common.utils.StringUtils;
import com.rede.didiok.sms.event.annotation.EventType;
import com.rede.didiok.sms.event.service.AbstractEventHandler;

/**
 * 关注事件处理器
 */
@Slf4j
@Component
@EventType({EntityType.WATCH})
public class WatchEventHandler extends AbstractEventHandler {

    @Override
    public void doEventHandler(DomainEvent domainEvent) {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        UserWatchDto userWatch = objectMapper.convertValue(domainEvent.getEntity(), UserWatchDto.class);
        switch (domainEvent.getEventAction()) {
            case WATCH_ADD: {
                this.add(userWatch);
            }
            break;
            case WATCH_CANCEL: {
                this.cancel(userWatch);
            }
            break;
        }
    }

    /**
     * 添加关注
     *
     * @param userWatch
     */
    public void add(UserWatchDto userWatch) {
        // 向被关注的用户推送消息通知
        NoticeDto notice = new NoticeDto();
        notice.setCreateUserUid(userWatch.getToUserUid());
        notice.setNoticeType(NoticeTypeEnum.WATCH.getCode());
        notice.setBusinessType(BusinessTypeEnum.USER_WATCH.getCode());
        notice.setBusinessUid(userWatch.getUid());
        userFeignClient.saveNotice(notice);

        // 同时向被关注的Redis发送通知
        String redisKey = RedisConf.USER_RECEIVE_WATCH_COUNT + Constants.SYMBOL_COLON + userWatch.getToUserUid();
        String watchCount = redisUtil.get(redisKey);
        if (StringUtils.isNotEmpty(watchCount)) {
            redisUtil.incrBy(redisKey, Constants.NUM_ONE);
        } else {
            redisUtil.setEx(redisKey, Constants.STR_ONE, 7, TimeUnit.DAYS);
        }

    }

    /**
     * 取消关注
     *
     * @param userWatch
     */
    public void cancel(UserWatchDto userWatch) {
        log.info("[WatchEventHandler] 取消关注事件暂未实现");
    }


}
